package com.gitee.wsl.doc.xml

import com.gitee.wsl.collections.stack.stackOf


class XmlEntityParser(
    val baseParser:MiniXmlPullParser,
    val header:EntityHandler
) {
    val namespaceManager:XmlNamespaceManager = XmlNamespaceManager()

    private val stack  = stackOf<XmlEntity.Element>()

    val encodingRegex = """<?xml.*encoding=["']([^"']+)["'].*?>""".toRegex()

//    fun findEncodingCharset(){
//        if (encodingCharset == null) {
//            val encodingContent = buildString { Charsets.UTF_8.decode( bytes) }
//            encodingCharset = findEncodingCharset(encodingRegex, encodingContent, charset)
//        }
//
//        currentBuffer =
//            buildString { (encodingCharset ?: charset).decode(this, bytes) }
//                .replace("&acirc;&#128;&#148;", "&ndash;")
//                .replace("&acirc;&#128;&#153;", "&apos;")
//    }


    init {
        header.onParserInit(this)
    }

    fun parser(){

        with(baseParser){
            while (eventType != EventType.END_DOCUMENT) {
                when(eventType){
                    EventType.START_DOCUMENT -> {
                        header.onStartDocument()
                    }
                    EventType.START_TAG ->{
                        val attrib = mutableListOf<XmlEntity.Attribute>()
                        (0..< attributeCount).forEach {
                            attrib.add(XmlEntity.Attribute(
                                getAttributeName(it),
                                getAttributeNamespace(it),
                                getAttributeValue(it)
                            ))
                        }
                        val element = XmlEntity.Element(name,namespace,attrib)
                        stack.push(element)
                        header.onStartElement(element)
                    }
                    EventType.END_TAG ->{
                        val element = stack.pop()
                        header.onEndElement(element)
                    }

                    EventType.TEXT ->{
                        header.onTextElement(stack.peek(),XmlEntity.Value(text))
                    }

                    EventType.COMMENT->{}
                    else -> {}
                }
            }
            header.onEndDocument()
        }
    }

}

interface EntityHandler{

    fun onParserInit(entityParser: XmlEntityParser) {}

    fun onStartDocument() {}

    fun onEndDocument() {}

    fun onStartElement(element: XmlEntity.Element)

    fun onEndElement(element: XmlEntity.Element)

    fun onTextElement(node: XmlEntity.Element,text:XmlEntity.Value)

}